Skip to content

feat: add SPEED (Spectral Progressive Diffusion) sampler#1761

Draft
fszontagh wants to merge 4 commits into
leejet:masterfrom
fszontagh:feat/speed-sampler
Draft

feat: add SPEED (Spectral Progressive Diffusion) sampler#1761
fszontagh wants to merge 4 commits into
leejet:masterfrom
fszontagh:feat/speed-sampler

Conversation

@fszontagh

@fszontagh fszontagh commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds speed_flow - the SPEED (Spectral Progressive Diffusion) sampler from arXiv:2605.18736. Runs the early steps of a flow model at reduced spatial resolution, expands to full resolution via a DCT spectral basis at scheduled transitions, and rescales the flow-matching time (paper kappa, Eqs. 5-6) so the base sampler continues cleanly. Training-free; works with any pretrained flow model.

Sampling-time speedups over euler at same seed / step count:

Model Config Speedup
Flux schnell Q4_K 1024x1024 8-step speed_scales=0.5:1.0 ~1.6x
Qwen Image Q2_K 1024x1024 20-step speed_scales=0.5:1.0 ~1.7x
Z-Image turbo Q8 1024x688 8-step speed_scales=0.5:1.0,speed_manual_sigmas=0.7 ~3.5x

Related Issue / Discussion

Closes #1756.

Reference impl: howardhx/speed, ruwwww/ComfyUI-SPEED.

Additional Information

What's in the PR

  • FFT and orthonormal DCT primitives on sd::Tensor<float> (src/core/spectral_ops.hpp).
  • The sampler and config parsing (src/runtime/speed_sampler.hpp).
  • Enum, name table, dispatch, CLI help.
  • Ref-latent resize helper in the denoise lambda so ref-guided models tolerate multi-resolution samplers without crashing (cached by target shape, no cost for the non-SPEED path).
  • Mask-shape guard at stable-diffusion.cpp:2534 so the auto-created ones-mask doesn't crash when x is downscaled.
  • Docs: docs/speed_sampler.md; pointer in docs/performance.md.
  • Byproduct: fixed a pre-existing (null) in sampling_methods_str[] for dpm++2m_sde / dpm++2m_sde_bt (never extended when those samplers were added).

Compatibility (verified locally on RTX 3060 12 GB)

  • --offload-to-cpu, --max-vram, --stream-layers: full, ~5 ms overhead per extra graph plan.
  • --cache-mode easycache and siblings: full.
  • Reference-latent models (Qwen Edit etc.): runs but source-image fidelity is reduced because low-res segments condition on a downscaled reference. A LOG_WARN fires when detected; docs cover the trade-off and how to tune around it.

Example (Qwen Image, 1024x1024, 20 steps, seed 42, cfg 2.5)

euler speed_flow
qwen_euler qwen_speed

Known limits (v1)

  • Naive O(N^2) 2D DCT. Fine for image latents, would need a proper FFT-based DCT for video.
  • Image latents only (4-D [W, H, C, N]).
  • Two ggml graph builds per generation (low-res, full-res); cached across steps in each segment.

Checklist

@leejet

leejet commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Thanks for the PR. The idea is interesting, but I don’t think it’s worth merging into master for now.

The visual quality is not very convincing to me, and the practical speedup also seems limited when compared with existing cache or Turbo LoRA workflows. At the same time, this adds quite a bit of extra code and maintenance burden for a sampler that may only be useful in some specific cases.

I’d prefer to keep this as experimental for now rather than merge it into the main branch.

@fszontagh fszontagh marked this pull request as draft July 7, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] SPEED - Spectral Progressive Diffusion for faster sampling.

2 participants